// created by noellynch
// May 15, 2011

package com.gruntdb.engines.indexedjson;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.gruntdb.core.GruntDataStore;
import com.gruntdb.core.stubs.IGruntDBIndex;
import com.gruntdb.objects.SizedOffset;

public class IndexedJSONStoreManager {
	public static final int MAX_ENTRIES_PER_FILE = 100;
	private		List<IndexedJSONSegmentFile>		mcl_segments;
	private		IndexedJSONStorageEngine	mcl_dataStore;
	
	private		boolean			mb_dirty;
	
	public	IndexedJSONStoreManager(IndexedJSONStorageEngine cl_store) {
		mcl_dataStore = cl_store;
		mcl_segments = new ArrayList<IndexedJSONSegmentFile>();
	}
	
	protected	void	initialise() {
		// get all segment files in location
		File		lcla_files[] = mcl_dataStore.getLocation().listFiles();
		
		for(File lcl_f : lcla_files) {
			if(lcl_f.getName().indexOf(mcl_dataStore.getFileReferenceName()) != -1) {
				if(lcl_f.getName().indexOf(".segment") != -1) {
					String		lstr_split[] = lcl_f.getName().split("\\Q_\\E");
					
					addSegment(Integer.parseInt(lstr_split[0]));
				}
			}
		}
	}
	
	protected	void	addSegment(int i_index) {
		IndexedJSONSegmentFile		lcl_file = new IndexedJSONSegmentFile(mcl_dataStore, i_index);
		mcl_segments.add(lcl_file);
	}
	
	public	IGruntDBIndex	saveToSegment(long l_id, String str_value) {
		IndexedJSONSegmentFile		lcl_segment = getSegment(l_id);
		if(lcl_segment == null) {
			lcl_segment = newSegment(l_id);
		}
		
		SizedOffset		lcl_result = lcl_segment.saveValue(str_value);
		IGruntDBIndex		lcl_idx = new IndexedJSONStorageIndex(l_id, lcl_result.getOffset(), 
				lcl_result.getSize(), lcl_segment.getFileIndex(), 0);
		
		return lcl_idx;
	}
	
	public	int		getNumSegments() {
		return mcl_segments.size();
	}
	
	public	IndexedJSONSegmentFile		getSegmentAt(int i_index) {
		return mcl_segments.get(i_index);
	}
	
	protected	boolean		isDirty() {
		synchronized (this) {
			return mb_dirty;
		}
	}
	
	protected	void		clearDirty() {
		synchronized (this) {
			mb_dirty = false;
		}
	}
	
	private	IndexedJSONSegmentFile	newSegment(long i_lowerIDX) {
		synchronized (this) {
			mb_dirty = true;
			
			int		li_index = mcl_segments.size();
			
			IndexedJSONSegmentFile		lcl_f = new IndexedJSONSegmentFile(mcl_dataStore, li_index);
			lcl_f.setLowerIndex(i_lowerIDX);
			lcl_f.setUpperIndex(i_lowerIDX + MAX_ENTRIES_PER_FILE);
			lcl_f.initialiseFile();
			
			mcl_segments.add(lcl_f);
			return lcl_f;
		}
		
	}
	
	private		IndexedJSONSegmentFile		getSegment(long l_id) {
		for(IndexedJSONSegmentFile lcl_f : mcl_segments) {
			if((lcl_f.getLowerIndex() <= l_id) && (lcl_f.getUpperIndex() >= l_id)) {
				return lcl_f;
			}
		}
		
		return null;
	}
}
